Add `--name` to `cargo test` and `cargo bench`
authorTomas Sedovic <tomas@sedovic.cz>
Tue, 28 Oct 2014 08:31:34 +0000 (09:31 +0100)
committerTomas Sedovic <tomas@sedovic.cz>
Wed, 29 Oct 2014 10:13:24 +0000 (11:13 +0100)
You can now run a single test/bench file by passing its name to `cargo
test` or `cargo bench`.

src/bin/bench.rs
src/bin/test.rs
src/cargo/ops/cargo_rustc/compilation.rs
src/cargo/ops/cargo_rustc/fingerprint.rs
src/cargo/ops/cargo_test.rs
tests/test_cargo_bench.rs
tests/test_cargo_test.rs

index 53fb6e3bfaa0dfec73674fd25e723f65ec5e12c3..56e441cfa6e99f425fe57212a86d3d7e5df56226 100644 (file)
@@ -11,6 +11,7 @@ struct Options {
     flag_package: Option<String>,
     flag_jobs: Option<uint>,
     flag_features: Vec<String>,
+    flag_name: Option<String>,
     flag_no_default_features: bool,
     flag_target: Option<String>,
     flag_manifest_path: Option<String>,
@@ -26,6 +27,7 @@ Usage:
 
 Options:
     -h, --help               Print this message
+    --name NAME              Name of the bench to run
     --no-run                 Compile, but don't run benchmarks
     -p SPEC, --package SPEC  Package to run benchmarks for
     -j N, --jobs N           The number of jobs to run in parallel
@@ -50,6 +52,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
     shell.set_verbose(options.flag_verbose);
 
     let mut ops = ops::TestOptions {
+        name: options.flag_name.as_ref().map(|s| s.as_slice()),
         no_run: options.flag_no_run,
         compile_opts: ops::CompileOptions {
             env: "bench",
index c4a24aa4ba815645afd72f18ea0b21db5db9adfa..0dd4d4c3066b731a26b2e212c946b8fadbd4cdec 100644 (file)
@@ -11,6 +11,7 @@ struct Options {
     flag_features: Vec<String>,
     flag_jobs: Option<uint>,
     flag_manifest_path: Option<String>,
+    flag_name: Option<String>,
     flag_no_default_features: bool,
     flag_no_run: bool,
     flag_package: Option<String>,
@@ -26,6 +27,7 @@ Usage:
 
 Options:
     -h, --help               Print this message
+    --name NAME              Name of the test to run
     --no-run                 Compile, but don't run tests
     -p SPEC, --package SPEC  Package to run tests for
     -j N, --jobs N           The number of jobs to run in parallel
@@ -49,6 +51,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
     shell.set_verbose(options.flag_verbose);
 
     let mut ops = ops::TestOptions {
+        name: options.flag_name.as_ref().map(|s| s.as_slice()),
         no_run: options.flag_no_run,
         compile_opts: ops::CompileOptions {
             env: "test",
index 8e8ddf6957b9ad64d4a9522e0df8818999f1dfb1..ebeeefe1f7c544a742516dc80f115a7bfe55bf11 100644 (file)
@@ -15,7 +15,7 @@ pub struct Compilation {
     pub libraries: HashMap<PackageId, Vec<Path>>,
 
     /// An array of all tests created during this compilation.
-    pub tests: Vec<Path>,
+    pub tests: Vec<(String, Path)>,
 
     /// An array of all binaries created.
     pub binaries: Vec<Path>,
index 64866ab3a83d1b2108bcaf0005169e955800dbf1..876a58fb6ebd767a6749f5eff25f92ce771ee319 100644 (file)
@@ -100,7 +100,7 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target,
             pairs.push((old_root.join(filename), root.join(filename)));
 
             if target.get_profile().is_test() {
-                cx.compilation.tests.push(dst.clone());
+                cx.compilation.tests.push((target.get_name().into_string(), dst.clone()));
             } else if target.is_bin() {
                 cx.compilation.binaries.push(dst.clone());
             } else if target.is_lib() {
index 387b3275102642627614a63fba87089551f92d78..426fe9f804f415af96f2c0356ca76fe832e19e91 100644 (file)
@@ -8,6 +8,7 @@ use util::{CargoResult, ProcessError};
 pub struct TestOptions<'a> {
     pub compile_opts: ops::CompileOptions<'a>,
     pub no_run: bool,
+    pub name: Option<&'a str>,
 }
 
 pub fn run_tests(manifest_path: &Path,
@@ -20,8 +21,13 @@ pub fn run_tests(manifest_path: &Path,
     if options.no_run { return Ok(None) }
     compile.tests.sort();
 
+    let target_name = options.name;
+    let mut tests_to_run = compile.tests.iter().filter(|&&(ref test_name, _)| {
+        target_name.map_or(true, |target_name| target_name == test_name.as_slice())
+    });
+
     let cwd = os::getcwd();
-    for exe in compile.tests.iter() {
+    for &(_, ref exe) in tests_to_run {
         let to_display = match exe.path_relative_from(&cwd) {
             Some(path) => path,
             None => exe.clone(),
@@ -39,6 +45,8 @@ pub fn run_tests(manifest_path: &Path,
         }
     }
 
+    if options.name.is_some() { return Ok(None) }
+
     if options.compile_opts.env == "bench" { return Ok(None) }
 
     let mut libs = compile.package.get_targets().iter().filter_map(|target| {
index d1d4da7959eec9595bee1423a2cdc70eefed2847..a661d795ee631884ab65fe2f5fbad2698c5b4a6d 100644 (file)
@@ -50,6 +50,47 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
         RUNNING)));
 })
 
+test!(bench_target_name {
+    let prj = project("foo")
+        .file("Cargo.toml" , r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [[bin]]
+            name="bin1"
+            path="src/bin1.rs"
+
+            [[bin]]
+            name="bin2"
+            path="src/bin2.rs"
+        "#)
+        .file("src/bin1.rs", r#"
+            extern crate test;
+            #[bench] fn run1(_ben: &mut test::Bencher) { }"#)
+        .file("src/bin2.rs", r#"
+            extern crate test;
+            #[bench] fn run2(_ben: &mut test::Bencher) { }"#);
+
+    let expected_stdout = format!("\
+{compiling} foo v0.0.1 ({dir})
+{runnning} target[..]release[..]bin2[..]
+
+running 1 test
+test run2 ... bench:         0 ns/iter (+/- 0)
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
+
+",
+       compiling = COMPILING,
+       runnning = RUNNING,
+       dir = prj.url());
+
+    assert_that(prj.cargo_process("bench").arg("--name").arg("bin2"),
+        execs().with_status(0).with_stdout(expected_stdout.as_slice()));
+})
+
 test!(cargo_bench_verbose {
     let p = project("foo")
         .file("Cargo.toml", basic_bin_manifest("foo").as_slice())
index 34c045449828849b6b540242f186c2811823fda6..901499c44d0d67fadcdf30341a047077226f3655 100644 (file)
@@ -867,6 +867,81 @@ test!(test_no_run {
                        dir = p.url()).as_slice()));
 })
 
+test!(test_run_specific_bin_target {
+    let prj = project("foo")
+        .file("Cargo.toml" , r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [[bin]]
+            name="bin1"
+            path="src/bin1.rs"
+
+            [[bin]]
+            name="bin2"
+            path="src/bin2.rs"
+        "#)
+        .file("src/bin1.rs", "#[test] fn test1() { }")
+        .file("src/bin2.rs", "#[test] fn test2() { }");
+
+    let expected_stdout = format!("\
+{compiling} foo v0.0.1 ({dir})
+{running} target[..]bin2-[..]
+
+running 1 test
+test test2 ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+",
+       compiling = COMPILING,
+       running = RUNNING,
+       dir = prj.url());
+
+    assert_that(prj.cargo_process("test").arg("--name").arg("bin2"),
+        execs().with_status(0).with_stdout(expected_stdout.as_slice()));
+})
+
+test!(test_run_specific_test_target {
+    let prj = project("foo")
+        .file("Cargo.toml" , r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/bin/a.rs", "fn main() { }")
+        .file("src/bin/b.rs", "#[test] fn test_b() { } fn main() { }")
+        .file("tests/a.rs", "#[test] fn test_a() { }")
+        .file("tests/b.rs", "#[test] fn test_b() { }");
+
+    let expected_stdout = format!("\
+{compiling} foo v0.0.1 ({dir})
+{running} target[..]b-[..]
+
+running 1 test
+test test_b ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+{running} target[..]b-[..]
+
+running 1 test
+test test_b ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+",
+       compiling = COMPILING,
+       running = RUNNING,
+       dir = prj.url());
+
+    assert_that(prj.cargo_process("test").arg("--name").arg("b"),
+        execs().with_status(0).with_stdout(expected_stdout.as_slice()));
+})
+
 test!(test_no_harness {
     let p = project("foo")
         .file("Cargo.toml", r#"